package com.ruoyi.project.mahjong.service.impl;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.*;

import cn.hutool.core.util.ObjectUtil;
import com.ruoyi.common.exception.BaseException;
import com.ruoyi.common.utils.DateRangeUtil;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.framework.redis.RedisCache;
import com.ruoyi.project.mahjong.domain.TRoom;
import com.ruoyi.project.mahjong.domain.TWork;
import com.ruoyi.project.mahjong.domain.enu.CostType;
import com.ruoyi.project.mahjong.domain.vo.*;
import com.ruoyi.project.mahjong.mapper.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.project.mahjong.domain.TRecord;
import com.ruoyi.project.mahjong.service.ITRecordService;

/**
 * 整体流水Service业务层处理
 *
 * @author ruoyi
 * @date 2023-10-07
 */
@Service
public class TRecordServiceImpl implements ITRecordService
{
    @Autowired
    private TRecordMapper tRecordMapper;
    @Autowired
    private TRoomMapper tRoomMapper;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private  TWorkServiceImpl workService;
    @Autowired
    private OtherPriceMapper otherPriceMapper;
    @Autowired
    private SendMoneyMapper sendMoneyMapper;
    @Autowired
    private TMemberLogMapper memberLogMapper;
    /**
     * 查询整体流水
     *
     * @param id 整体流水ID
     * @return 整体流水
     */
    @Override
    public TRecord selectTRecordById(Long id)
    {
        return tRecordMapper.selectTRecordById(id);
    }

    /**
     * 查询整体流水列表
     *
     * @param tRecord 整体流水
     * @return 整体流水
     */
    @Override
    public List<TRecord> selectTRecordList(TRecord tRecord)
    {
        return tRecordMapper.selectTRecordList(tRecord);
    }

    /**
     * 新增整体流水
     *
     * @param tRecord 整体流水
     * @return 结果
     */
    @Override
    public int insertTRecord(TRecord tRecord)
    {
        tRecord.setCreateTime(DateUtils.getNowDate());
        return tRecordMapper.insertTRecord(tRecord);
    }

    /**
     * 修改整体流水
     *
     * @param tRecord 整体流水
     * @return 结果
     */
    @Override
    public int updateTRecord(TRecord tRecord)
    {
        tRecord.setUpdateTime(DateUtils.getNowDate());
        return tRecordMapper.updateTRecord(tRecord);
    }

    /**
     * 批量删除整体流水
     *
     * @param ids 需要删除的整体流水ID
     * @return 结果
     */
    @Override
    public int deleteTRecordByIds(Long[] ids)
    {
        return tRecordMapper.deleteTRecordByIds(ids);
    }

    /**
     * 删除整体流水信息
     *
     * @param id 整体流水ID
     * @return 结果
     */
    @Override
    public int deleteTRecordById(Long id)
    {
        return tRecordMapper.deleteTRecordById(id);
    }

    @Override
    public AllIncomeTypeMoneyVo selectRecordAllIncomeTypeMoney(Long shopId, String startTime, String endTime) {
        AllIncomeTypeMoneyVo allIncomeTypeMoney =new AllIncomeTypeMoneyVo();
        allIncomeTypeMoney.setCashIncome(tRecordMapper.getXjsr(shopId,startTime,endTime));
        allIncomeTypeMoney.setScanMoney(tRecordMapper.getSmsr(shopId,startTime,endTime));
        allIncomeTypeMoney.setOtherIncome(tRecordMapper.getQtsr(shopId,startTime,endTime));
        double income = Double.parseDouble(allIncomeTypeMoney.getCashIncome()) + Double.parseDouble(allIncomeTypeMoney.getScanMoney()) + Double.parseDouble(allIncomeTypeMoney.getOtherIncome());
        allIncomeTypeMoney.setReceiveMoney(String.valueOf(income));
        allIncomeTypeMoney.setOtherRefundMoney(tRecordMapper.getQtzc(shopId,startTime,endTime));
        allIncomeTypeMoney.setRefundMoney(tRecordMapper.getTkze(shopId,startTime,endTime));
        double refundMoney = Double.parseDouble(allIncomeTypeMoney.getOtherRefundMoney()) + Double.parseDouble(allIncomeTypeMoney.getRefundMoney());
        allIncomeTypeMoney.setRevenueMoney(String.valueOf(income - refundMoney));
        return allIncomeTypeMoney;
    }

    @Override
    public ReceiveVo selectRealTimeData(Long shopId ,String startTime, String endTime) {

        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
       if (ObjectUtil.isNull(startTime)||endTime==""){
           calendar.add(Calendar.MONTH, 0);
           calendar.set(Calendar.DAY_OF_MONTH, 1);
           startTime=  dateFormat.format(calendar.getTime()) + " 00:00:00";
       }
        if (ObjectUtil.isNull(endTime)||endTime==""){
//            String firstDayOfMonth = dateFormat.format(calendar.getTime()) + " 00:00:00";
            calendar.add(Calendar.MONTH, 1);
            calendar.set(Calendar.DAY_OF_MONTH, 0);
            endTime= dateFormat.format(calendar.getTime()) + " 23:59:59";

        }
         TRoom room = new TRoom();
        room.setBak1(shopId.toString());
        //       包房、公厅
         List<TRoom> rooms = tRoomMapper.selectTRoomList(room);
        List<CategorizeListVo> v=new ArrayList<>();
         if (ObjectUtil.isNotNull(rooms)){
            for (TRoom tRoom : rooms) {
                List <CategorizeIncomeVo>  ctVo= tRecordMapper.selectRoomIncome(shopId,startTime,endTime,tRoom.getId());
                CategorizeListVo categorizeListVo = new CategorizeListVo();
                categorizeListVo.setCategorizeIncomeVos(ctVo);
                v.add(categorizeListVo);
            }
         }
//      商品收入
        List <RealTimeDataVo>  productCost=tRecordMapper.selectProductCost(shopId,startTime,endTime);
//      赠送金额
        List <RealTimeDataVo> giveMoney= tRecordMapper.selectGiveMoney(shopId,startTime,endTime);
//       消费金额
        List <RealTimeDataVo> costMoney  =tRecordMapper.selectRecordCostMoney(shopId,startTime,endTime);
         ReceiveVo receiveVo = new ReceiveVo();
        receiveVo.setIncomeVos(v);
        receiveVo.setProductCost(productCost);
        receiveVo.setGiveMoney(giveMoney);
        receiveVo.setCostMoney(costMoney);

        return receiveVo;
    }
    @Override
    public List<Map<String,Object>> selectTableCollectList(Long shopId ,String startTime, String endTime) {
        return tRecordMapper.selectTableCollectList(shopId,startTime,endTime);
    }
////        List<Long> roomIds=new ArrayList<>();
////        for (CategorizeIncomeVo vo : ctVo) {
////            roomIds.add(vo.getRoomId());
////        }
////        CategorizeListVo categorizeListVo = new CategorizeListVo();
////        for (Long roomId : roomIds) {
////            List <CategorizeIncomeVo> voList=new ArrayList<>();
////            for (CategorizeIncomeVo vo : ctVo) {
////                if (vo.getRoomId()==roomId){
////                    voList.add(vo);
////                }
////
////            }
////            categorizeListVo.setCategorizeIncomeVos(voList);
////        }
    @Override
    public Map<String, Object> selectCashAndTableCost(Long shopId, String startTime, String endTime) {
        if (null == startTime || startTime.equals("")){
            String[] weekRange = DateRangeUtil.getWeekRange(new Date());
            startTime = weekRange[0];
            endTime = weekRange[1];
        }
        List<Map<String, Object>> list = tRecordMapper.selectCashCost(shopId, startTime, endTime);
        // 获取区间内的每一天时间
        List<String> datesInRange = DateRangeUtil.getDatesInRange(startTime, endTime);
        LinkedHashMap<String,Double> productValues = new LinkedHashMap<>();
        LinkedHashMap<String,Double> topUpValues = new LinkedHashMap<>();
        LinkedHashMap<String,Double> refundValues = new LinkedHashMap<>();
        LinkedHashMap<String,Double> OtherValues = new LinkedHashMap<>();
        for (String string : datesInRange) {
            productValues.put(string,0.0);
            topUpValues.put(string,0.0);
            refundValues.put(string,0.0);
            OtherValues.put(string,0.0);
        }

        for (String str : datesInRange) {
            for (Map<String, Object> map : list) {
                if (str.equals(map.get("createTime"))){
                    String type = String.valueOf(map.get("type"));
                    String time = String.valueOf(map.get("createTime"));
                    Double receiveMoney = Double.valueOf(map.get("receiveMoney").toString());
                    Double refundMoney = Double.valueOf(map.get("refundMoney").toString());
                    switch (type){
                        case "-1":
                            productValues.put(time,receiveMoney);
                            break;
                        case "-2":
                            topUpValues.put(time,receiveMoney);
                            break;
                        case "-3":
                            refundValues.put(time,refundMoney);
                            break;
                        case "-4":
                            OtherValues.put(time,receiveMoney);
                            break;
                    }
                }
            }
        }
        Map<String,Object> map = new HashMap<>();
        map.put("times",datesInRange);
        map.put("productValues",productValues.values());
        map.put("topUpValues",topUpValues.values());
        map.put("refundValues",refundValues.values());
        map.put("OtherValues",OtherValues.values());
        return map;
    }

    @Override
    public List<MemberRechargeVo> selectMemberIdRecharge(Long shopId, Date startTime, Date endTime, String phone) {
        List<MemberRechargeVo> res= tRecordMapper.selectMemberIdRecharge(shopId,startTime,endTime,phone);
        return res;
    }

    @Override
    public List<MemberCostRecordVo> selectCostRecord(Long shopId, String startTime, String endTime, String id) {
        List<MemberCostRecordVo> memberCostRecordVos= tRecordMapper.selectCostRecord(shopId,startTime,endTime,id);
        if (ObjectUtil.isEmpty(memberCostRecordVos)){
            throw  new BaseException("暂无会员消费信息");
        }
        List<Long> roomIds=new ArrayList<>();
        for (MemberCostRecordVo vo : memberCostRecordVos) {
            roomIds.add(Long.valueOf(vo.getCostType()));
        }
        List<TRoom> room=tRoomMapper.selectRoomByRoomIds(roomIds);
        for (TRoom tRoom : room) {
             Long roomId = tRoom.getId();
            for (MemberCostRecordVo vo : memberCostRecordVos) {
                 Long costType = Long.valueOf(vo.getCostType());
                 if (costType==roomId){
                     vo.setCostTypeName(tRoom.getRoomName());
                     break;
                 }
            }
        }
        return memberCostRecordVos;
    }

    @Override
    public List<RechargeRankingVo> selectMemberRechargeList(Long shopId, String startTime, String endTime, String status) {
        if (status.equals("1")){
           return tRecordMapper.selectMemberRechargeList(shopId, startTime, endTime);
        }
        if (status.equals("2")){
            return tRecordMapper.selectMemberCostList(shopId, startTime, endTime);
        }
        throw  new BaseException("选择查询状态");
    }

    @Override
    public ShiftMoneyInfoVo selectShiftMoneyInfo(String startTime, String endTime, Long shopId,Long userId) {


        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        Long   jbid  = redisCache.getCacheObject(shopId+userId.toString());

        if (ObjectUtil.isNull(jbid)){
            throw  new BaseException("当前无人上班");
        }
         TWork tWork1 = workService.selectTWorkById(jbid);
        if (ObjectUtil.isNull(tWork1)){
            redisCache.deleteObject(shopId+userId.toString());
            throw  new BaseException("当前无人上班");
        }
        String sbTime = null;
        try {
            sbTime=  sdf.format(tWork1.getSbTime());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        String xbTime = null;
        try {
            if(null!=tWork1.getXbTime()){
                xbTime= endTime==null? sdf.format(tWork1.getXbTime()):null;
            }

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        BigDecimal allMoney =new BigDecimal(0);
        ShiftMoneyInfoVo vo =new ShiftMoneyInfoVo();

         List <RecordIncomeType> incomeType = tRecordMapper.selectShiftMoneyInfo(sbTime, xbTime, shopId,jbid.toString());
      /* if (ObjectUtil.isEmpty(incomeType)){
           throw  new BaseException("当前交班暂无收银记录");
       }*/
      /*  for (RecordIncomeType type : incomeType) {
            if (ObjectUtil.isNotNull(type.getType())&&type.getType().equals("2")){
                vo.setCashMoney(type.getMoney());
                allMoney=allMoney.add(new BigDecimal(type.getMoney())).setScale(2);
            }
            if (ObjectUtil.isNotNull(type.getType())&&type.getType().equals("1")){
                allMoney=allMoney.add(new BigDecimal(type.getMoney())).setScale(2);
                vo.setScanMoney(type.getMoney());
            }
        }*/
        TWork tWork = workService.selectTWorkById(jbid);
        vo.setInitMoney(tWork.getInitMoney().toString());
        allMoney =allMoney.add(new BigDecimal(tWork.getInitMoney().toString())).setScale(2);
        vo.setAllMoney(allMoney.toString());
        //现金
       // String paymentMoney = tRecordMapper.selectIncomeMoney(jbid,"2");
        String paymentMoney = memberLogMapper.selectSumByjb(tWork.getSbTime(),tWork.getXbTime(),shopId).toString();
        vo.setCashMoney(paymentMoney);
        allMoney=allMoney.add(new BigDecimal(paymentMoney));
        //线上 TODO 20240401去除了线上哦总额
       // String scanMoney = tRecordMapper.selectIncomeMoney(jbid,"1");
      //  vo.setScanMoney(scanMoney);
      //  allMoney=allMoney.add(new BigDecimal(scanMoney));
        //其他收入
        String otherMoney = otherPriceMapper.selectOtherMoney(tWork.getStaffId(),DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,tWork.getSbTime()), endTime,shopId,"0");

        vo.setOtherMoney(otherMoney);
        allMoney = allMoney.add(new BigDecimal(otherMoney));
        // 支出金额
        String outMoney = otherPriceMapper.selectOtherMoney(tWork.getStaffId(),DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,tWork.getSbTime()), endTime,shopId,"1");

        vo.setOutMoney(outMoney);
        allMoney = allMoney.subtract(new BigDecimal(outMoney));
        // 退款收入
        String refundMoney = tRecordMapper.selectRefundMoney(jbid,DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,tWork.getSbTime()), endTime,shopId);

        vo.setRefendMoney(new BigDecimal(refundMoney));
        allMoney = allMoney.subtract(new BigDecimal(refundMoney));
        BigDecimal sendMoeny=sendMoneyMapper.countByJbId(jbid);
        vo.setSendMoney(sendMoeny);
        allMoney = allMoney.subtract(sendMoeny);
        vo.setAllMoney(allMoney.toString());
        return vo ;
    }
    private static Date getStartTime() {
        Calendar todayStart = Calendar.getInstance();
        todayStart.set(Calendar.HOUR, 0);
        todayStart.set(Calendar.MINUTE, 0);
        todayStart.set(Calendar.SECOND, 0);
        todayStart.set(Calendar.MILLISECOND, 0);
        return todayStart.getTime();
    }

    private static Date getEndTime() {
        Calendar todayEnd = Calendar.getInstance();
        todayEnd.set(Calendar.HOUR, 23);
        todayEnd.set(Calendar.MINUTE, 59);
        todayEnd.set(Calendar.SECOND, 59);
        todayEnd.set(Calendar.MILLISECOND, 999);
        return todayEnd.getTime();
    }

    @Override
    public Integer updateTRecordByJbId(TRecord record) {
        return tRecordMapper.updateTRecordByJbId(record);
    }

    @Override
    public List<WorkRecordVo> selectWorkRecordList(String startTime, String endTime, Long shopId) {
        return tRecordMapper.selectWorkRecordList(startTime,endTime,shopId);
    }

    @Override
    public List<ProductRecordInfoVo> selectReceive( List<Long> ids) {
        return tRecordMapper.selectReceive(ids);
    }

    @Override
    public List<RoomRecordInfoVo> selectRoomReceive(List<Long> ids) {
        return tRecordMapper.selectRoomReceive(ids);
    }

    @Override
    public OpenTableRateVo selectOenTableRate(Long shopId) {
         OpenTableRateVo vo = tRecordMapper.selectOenTableRate(shopId);
        BigDecimal i=new BigDecimal(0);
         if (vo.getAllTableNumber()!=0){
              BigDecimal bigDecimal = new BigDecimal(vo.getOpenTableNumber()).divide(new BigDecimal(vo.getAllTableNumber()),2, RoundingMode.HALF_UP);

             i = (bigDecimal).multiply(new BigDecimal(100));
         }
         vo.setOpenTableRateNumber(Double.valueOf(i.toString()));
         return vo;
    }

    @Override
    public Integer addReceive(TRecord record) {
        Long   jbid  = redisCache.getCacheObject(record.getShopId()+record.getStaffId().toString());
         if (ObjectUtil.isNull(jbid)){
             throw new BaseException("当前无人上班");
         }
        record.setIncomeProjectType(CostType.OTHER.getValue());//手动增加额外收入
        record.setOrderNumber(orderMethod());
        record.setHandoverId(jbid.toString());
        return tRecordMapper.addReceive(record);
    }

    @Override
    public Integer updateDefault(Long costId, Long shopId) {

        return tRecordMapper.updateDefault(costId,shopId);
    }

    @Override
    public List<OtherReceiveVo> selectOtherReceive(List<Long> ids) {
        return tRecordMapper.selectOtherReceive(ids);
    }

    @Override
    public List<TRecord> selectTopUpOrRefundList(Long shopId, String type, String startTime, String endTime, String deskId, String staffName) {

        return tRecordMapper.selectTopUpOrRefundList(shopId,type,startTime,endTime,deskId,staffName);
    }

    @Override
    public List<TRecord> deskMoneyList(Long shopId, String startTime, String endTime, String deskId, String staffName) {
        return tRecordMapper.selectDeskMoenyList(shopId,startTime,endTime,deskId,staffName);
    }

    public String orderMethod(){
        Random random = new Random();
        int i = random.nextInt(9000)+1000;
        return   String.valueOf( System.currentTimeMillis()+i);
    }

}
